<script lang="tsx">
import { ElForm, ElFormItem } from 'element-plus';
import { defineComponent, ref, computed, useSlots } from 'vue';
import { ResponsiveRow } from '@/components/ResponsiveRow';
import { proFormProps } from './types';
import { extractAttrsEvent } from '@/core/utils/install';
import { get } from 'lodash-es';

export default defineComponent({
  name: 'ProForm',
  props: proFormProps,
  setup(props, { expose }) {
    const elementRef = ref<InstanceType<typeof ElForm>>();
    const $slots = useSlots();
    const noop = () => {
      throw new Error('无法调用element对应方法，请检查组件ref属性是否绑定元素');
    };
    const validate = computed(() => elementRef.value?.validate ?? noop);
    const validateField = computed(() => elementRef.value?.validateField ?? noop);
    const resetFields = computed(() => elementRef.value?.resetFields ?? noop);
    const scrollToField = computed(() => elementRef.value?.scrollToField ?? noop);
    const clearValidate = computed(() => elementRef.value?.clearValidate ?? noop);
    const renderChildren = computed(() => {
      return props.config
        .filter((v) => {
          const { isHidden = false } = v;
          return !isHidden;
        })
        .map((v) => {
          const { render, renderLabel, renderError, slotName, ...rest } = v;
          const isOnlyText = !render && !slotName;
          return (
            <ElFormItem
              {...rest}
              v-slots={{
                label: renderLabel,
                error: renderError,
              }}
            >
              {isOnlyText
                ? get(props.model, v.prop)
                : slotName
                  ? $slots[slotName]?.({ model: props.model })
                  : render?.(props.model)}
            </ElFormItem>
          );
        });
    });
    expose({
      validate,
      validateField,
      resetFields,
      scrollToField,
      clearValidate,
      elementRef,
    });
    return {
      validate,
      validateField,
      resetFields,
      scrollToField,
      clearValidate,
      elementRef,
      renderChildren,
    };
  },
  render() {
    const { col, config, ...rest } = this.$props;
    const attrs = extractAttrsEvent(this.$attrs);
    return (
      <ElForm {...rest} {...attrs} ref="elementRef">
        <ResponsiveRow col={col}>{this.renderChildren}</ResponsiveRow>
      </ElForm>
    );
  },
});
</script>
